/**
 * Title: DateUtil.java<br/>
 * Description: <br/>
 * Copyright: Copyright (c) 2015<br/>
 * Company: gigold<br/>
 */
package com.hktf.uilib.utils;

import com.hktf.uilib.utils.MethodUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.UUID;

/**
 * Title: DateUtil<br/>
 * Description: <br/>
 * Company: gigold<br/>
 *
 * @author xie_lp
 * @date 2015-11-24上午9:40:43 时间格式转换工具类
 */
public class DateUtil {
    private static DateUtil instance;
    public String commonFormat = "yyyy-MM-dd HH:mm:ss";//常用的时间格式

    private DateUtil() {

    }

    public static DateUtil getInstance() {

        if (instance == null) {

            instance = new DateUtil();

        }

        return instance;

    }

    public final SimpleDateFormat sdf = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    public final SimpleDateFormat simpleDateFormat_HHmm = new SimpleDateFormat(
            "HH:mm");

    public final SimpleDateFormat sdfSub = new SimpleDateFormat(
            "yyyy-MM-dd 00:00:00");

    public final SimpleDateFormat sdfSub1 = new SimpleDateFormat("yyyy-MM-dd");

    public static final String sdfString1 = "yyyy-MM-dd";
    /**
     * 定义时间类型常量
     */

    public final static int SECOND = 1;

    public final static int MINUTE = 2;

    public final static int HOUR = 3;

    public final static int DAY = 4;

    private final static int WEEKDAYS = 7;
    private static String[] WEEK = {"星期天", "星期一", "星期二", "星期三", "星期四", "星期五",
            "星期六"};
    /**
     * 简单日期格式
     */
    public final SimpleDateFormat sdfDateSimple = new SimpleDateFormat(
            "yyyyMMdd");
    /**
     * 利用时间差来记录时间<br>
     * <p/>
     * 平台时间比本地时间快多少(可能为负),<br>
     * <p/>
     * 若没设置则span = 0,认为本地时间就是平台时间
     */

    private long span = 0;

    /**
     * 获取当前时间 Title: getDate<br/>
     * Description: <br/>
     *
     * @return Date
     * @author xie_lp
     * @date 2015-11-24上午9:43:16
     */
    public Date getDate() {
        Date nowAndroid = new Date();
        long nowPlant = nowAndroid.getTime() + span;
        Date nowPlantDate = new Date(nowPlant);

        return nowPlantDate;
    }

    public Calendar getCalendar() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getDate());
        return cal;

    }

    /**
     * 把平台时间转为本地时间（闹钟用到此接口） Title: getAndroidCalendar<br/>
     * Description: <br/>
     *
     * @param plantCalendar
     * @return
     * @author xie_lp
     * @date 2015-11-24上午9:45:15
     */
    public Calendar getAndroidCalendar(Calendar plantCalendar) {

        Calendar cal = Calendar.getInstance();
        Date plantDate = plantCalendar.getTime();
        cal.setTime(getAndroidDate(plantDate));
        return cal;
    }

    public Date getAndroidDate(Date plantDate) {
        long nowAndroid = plantDate.getTime() - span;
        Date androidDate = new Date(nowAndroid);
        return androidDate;

    }

    /**
     * 获取当前时间 Title: getDateString<br/>
     * Description: <br/>
     *
     * @return 返回字符串：yyyy-MM-dd HH:mm:ss
     * @author xie_lp
     * @date 2015-11-24上午9:46:11
     */
    public String getDateString() {
        Date date = getDate();
        return sdf.format(date);
    }

    /**
     * 根据要定义的格式返回当前时间 Title: getDateStringByFormatString<br/>
     * Description: <br/>
     *
     * @param fomatString
     * @return
     * @author xie_lp
     * @date 2015-11-24上午9:47:53
     */
    public String getDateStringByFormatString(String fomatString) {
        Date date = getDate();
        SimpleDateFormat df = new SimpleDateFormat(fomatString);
        return df.format(date);
    }

    /**
     * 将时间转换成格式为yyyy-MM-dd HH:mm:ss的字符串 Title: getDateString<br/>
     * Description: <br/>
     *
     * @param date
     * @return
     * @author xie_lp
     * @date 2015-11-24上午9:50:29
     */
    public String getDateString(Date date) {
        return sdf.format(date);
    }

    /**
     * 获取指定日期时间的增加偏移量后格式化的字符串 Title: getSpecifyDateStringByDayOffset<br/>
     * Description: <br/>
     *
     * @param day 天数偏移量
     * @return 格式化的日期时间字符串
     * @author xie_lp
     * @date 2015-11-24上午9:52:50
     */
    public String getSpecifyDateStringByDayOffset(int day) {
        Calendar calendar = getCalendar();
        calendar.add(Calendar.DAY_OF_YEAR, day);
        return getDayCalendar(calendar);
    }

    /**
     * 获取指定日期时间的增加偏移量后格式化的字符串 Title: getSpecifyDateStringByWeekOffset<br/>
     * Description: <br/>
     *
     * @param week 周数偏移量
     * @return 格式化的日期时间字符串
     * @author xie_lp
     * @date 2015-11-24上午9:54:14
     */
    public String getSpecifyDateStringByWeekOffset(int week) {
        Calendar calendar = getCalendar();
        calendar.add(Calendar.WEEK_OF_YEAR, week);
        calendar.add(
                Calendar.DAY_OF_YEAR,
                -(calendar.get(Calendar.DAY_OF_WEEK) == 1 ? 8 : calendar
                        .get(Calendar.DAY_OF_WEEK)) + 2);
        return getDayCalendar(calendar);
    }

    /**
     * 获取指定日期时间的增加偏移量后格式化的字符串 Title: getSpecifyDateStringByMonthOffset<br/>
     * Description: <br/>
     *
     * @param month 月数偏移量
     * @return 格式化的日期时间字符串
     * @author xie_lp
     * @date 2015-11-24上午9:55:10
     */
    public String getSpecifyDateStringByMonthOffset(int month) {
        Calendar calendar = getCalendar();
        calendar.add(Calendar.MONTH, month);
        return getDayCalendar(calendar);
    }

    /**
     * 获取指定日期时间的增加偏移量后格式化的字符串 Title: getSpecifyDateStringByMinuteOffset<br/>
     * Description: <br/>
     *
     * @param minute 分钟偏移量
     * @return 格式化的日期时间字符串
     * @author xie_lp
     * @date 2015-11-24上午9:57:36
     */
    public String getSpecifyDateStringByMinuteOffset(int minute) {
        Calendar calendar = getCalendar();
        calendar.add(Calendar.MINUTE, minute);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:00");
        return df.format(calendar.getTime());
    }

    public String getDayCalendar(Calendar calendar) {
        String calendarSub = sdfSub.format(calendar.getTime());
        return calendarSub;
    }

    /**
     * 将时间转换到指定格式的字符串 Title: convertDateToString<br/>
     * Description: <br/>
     *
     * @param date   时间类
     * @param format 指定格式:如果为null则默认为yyyy-MM-dd HH:mm:ss格式
     * @return
     * @author xie_lp
     * @date 2015-11-24上午9:59:59
     */
    public String convertDateToString(Date date, String format) {
        if (date == null) {
            return null;
        }
        if (format == null) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String result = sdf.format(date);

        return result;
    }

    /**
     * 从yyyy-MM-dd HH:mm:ss 格式的时间里面取出 ddHHmmss Title: convertFormatDataToString<br/>
     * Description: <br/>
     *
     * @param date yyyy-MM-dd HH:mm:ss 格式的时间
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:02:09
     */
    public String convertFormatDataToString(String date) {
        String[] datesplite = date.split(" ");
        String[] before = datesplite[0].split("-");
        String[] after = datesplite[1].split(":");
        StringBuilder builder = new StringBuilder();
        builder.append(before[2]).append(after[0]).append(after[1])
                .append(after[2]);

        return builder.toString();

    }

    /**
     * 将formatStr的时间 转成 long Title: formatDateStringToLong<br/>
     * Description: <br/>
     *
     * @param date
     * @param formatStr
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:04:52
     */
    public Long formatDateStringToLong(String date, String formatStr) {
        SimpleDateFormat formatter = new SimpleDateFormat(formatStr);
        try {
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
            return formatter.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0l;
    }

    /**
     * 将long型的时间转换成格式为HH:mm的字符串时间 Title: getTimeByHHmm<br/>
     * Description: <br/>
     *
     * @param time
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:09:33
     */
    public String getTimeByHHmm(long time) {
        String calendarSub = simpleDateFormat_HHmm.format(time);
        simpleDateFormat_HHmm.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return calendarSub;
    }

    /**
     * 把字符串型的时间 转化为 HH:mm格式 Title: getTimeByHHmm<br/>
     * Description: <br/>
     *
     * @param date
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:12:05
     */
    public String getTimeByHHmm(String date) {
        String result = "";
        if (!MethodUtils.getInstance().judgeStrIsEmpty(date)) {
            Long time = formatDateStringToLong(date, "yyyy-MM-dd HH:mm:ss");
            return getTimeByHHmm(time);
        }
        return result;
    }

    /**
     * 计算时间间隔(秒) Title: getIntervalSecond<br/>
     * Description: <br/>
     *
     * @param lastEndTime      上一次结束时间
     * @param currentBeginTime 这一次开始时间
     * @param timeFormatStr    时间格式
     * @return long
     * @author xie_lp
     * @date 2015-11-24上午10:13:11
     */
    public long getIntervalSecond(String lastEndTime, String currentBeginTime,
                                  String timeFormatStr) {
        long dlast, dbegin, dInterval;
        SimpleDateFormat df = new SimpleDateFormat(timeFormatStr);
        try {
            dlast = df.parse(lastEndTime).getTime();
            dbegin = df.parse(currentBeginTime).getTime();
            dInterval = Math.abs((dbegin - dlast) / 1000);// 时间间隔
        } catch (Exception e) {
            dInterval = 0;
            e.printStackTrace();
        }

        return dInterval;
    }

    /**
     * 根据秒数，计算时间 Title: computSecond<br/>
     * Description: <br/>
     *
     * @param time
     * @return mm:ss(String)
     * @author xie_lp
     * @date 2015-11-24上午10:14:51
     */
    public String computSecond(long time) {
        long minute = time % 3600 / 60;// 分
        long second = time % 60;// 秒

        return String.valueOf((minute < 10 ? ("0" + minute) : minute) + ":"
                + (second < 10 ? ("0" + second) : second));
    }

    /**
     * 根据秒数，计算时间 Title: computSecondToFullTime<br/>
     * Description: <br/>
     *
     * @param time
     * @return hh:mm:ss
     * @author xie_lp
     * @date 2015-11-24上午10:16:32
     */
    public String computSecondToFullTime(long time) {
        long hour = time / 3600;// 时
        long minute = time % 3600 / 60;// 分
        long second = time % 60;// 秒

        return String.valueOf((hour < 10 ? ("0" + hour) : hour) + ":"
                + (minute < 10 ? ("0" + minute) : minute) + ":"
                + (second < 10 ? ("0" + second) : second));
    }

    /**
     * 将srcFormat格式的srcDateStr时间转换成descFormat格式 Title:
     * convertStringDateToFormatString<br/>
     * Description: <br/>
     *
     * @param srcDateStr
     * @param srcFormat
     * @param descFormat
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:18:36
     */
    public String convertStringDateToFormatString(String srcDateStr,
                                                  String srcFormat, String descFormat) {
        if (srcDateStr == null || "".equals(srcDateStr)) {
            return "";
        } else {
            long longTime = formatDateStringToLong(srcDateStr, srcFormat);

            return formatDateLongToString(longTime, descFormat);
        }

    }

    /**
     * 将long型格式转换成descFormat格式的String型时间 Title: formatDateLongToString<br/>
     * Description: <br/>
     *
     * @param timeLongVal
     * @param descFormat
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:18:51
     */
    public String formatDateLongToString(Long timeLongVal, String descFormat) {
        Date date = new Date(timeLongVal);
        SimpleDateFormat df = new SimpleDateFormat(descFormat);

        return df.format(date);
    }

    /**
     * 将一个表示时间段的数转换为毫秒数 Title: formatToTimeMillis<br/>
     * Description: <br/>
     *
     * @param num  时间差数值,支持小数
     * @param type 时间类型：1为秒,2为分钟,3为小时,4为天
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:33:52
     */
    public long formatToTimeMillis(double num, int type) {
        if (num <= 0)
            return 0;
        switch (type) {
            case SECOND:
                return (long) (num * 1000);
            case MINUTE:
                return (long) (num * 60 * 1000);
            case HOUR:
                return (long) (num * 60 * 60 * 1000);
            case DAY:
                return (long) (num * 24 * 60 * 60 * 1000);

            default:
                return -1;
        }
    }

    /**
     * 判断活动开始和结束时间是否在一定的区间内 Title: judgeData<br/>
     * Description: <br/>
     *
     * @param num         时间差数值
     * @param type        时间类型：1为秒,2为分钟,3为小时,4为天
     * @param dataSoure
     * @param dataCompare
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:36:31
     */
    public boolean judgeData(int num, int type, Date dataSoure, Date dataCompare) {
        long nowLong = dataSoure.getTime();
        long beforeLong = dataCompare.getTime();
        long gapLong = formatToTimeMillis(num, type);
        if (Math.abs(nowLong - beforeLong) > gapLong) {
            return true;
        }
        return false;
    }

    /**
     * 日期变量转成对应的日期+星期字符串 Title: DateToWeek<br/>
     * Description: <br/>
     *
     * @param date
     * @return
     * @author xie_lp
     * @date 2015-12-9下午2:03:48
     */
    public String dateToWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayIndex = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayIndex < 1 || dayIndex > WEEKDAYS) {
            return null;
        }
        String dateStr = convertDateToString(date, "MM-dd");
        return dateStr + "  " + WEEK[dayIndex - 1];
    }

    /**
     * 将String格式转换成时间格式 Title: formatStringToDate<br/>
     * Description: <br/>
     *
     * @param dateStr
     * @param descFormat 格式
     * @return Date
     * @author xie_lp
     * @date 2015-11-24上午10:41:06
     */
    public Date formatStringToDate(String dateStr, String descFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(descFormat);
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static String getOrderIdByUUId() {
        int machineId = 1;//最大支持1-9个集群机器部署
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if(hashCodeV < 0) {//有可能是负数
            hashCodeV = - hashCodeV;
        }
        // 0 代表前面补充0
        // 4 代表长度为4
        // d 代表参数为正数型
        return machineId + String.format("%015d", hashCodeV);
    }
    /**
     * 根据类型返回开始日期和结束日期的对象 Title: getTimeScopeByState<br/>
     * Description: <br/>
     *
     * @param queryTimeType
     * @return
     * @author xie_lp
     * @date 2015-11-24上午10:44:50
     */
    public TimeScope getTimeScopeByState(String queryTimeType) {

        TimeScope retObj = new TimeScope();

        if ("TODAY".equals(queryTimeType)) {
            // 今天
            retObj.setBeginDate(convertDateToString(getDate(), "yyyyMMdd"));
            retObj.setEndDate(convertDateToString(getDate(), "yyyyMMdd"));
        } else if ("CURRENTMONTH".equals(queryTimeType)) {

            // 本月
            Calendar calendar = new GregorianCalendar();
            // 方式一，取本月第一天到最后一天的日期

            calendar.set(Calendar.DATE, 1);
            retObj.setBeginDate(convertDateToString(calendar.getTime(),
                    "yyyyMMdd"));
            calendar.roll(Calendar.DATE, -1);
            retObj.setEndDate(convertDateToString(calendar.getTime(),
                    "yyyyMMdd"));

            // 方式二，取从31天前到今天的日期
            // calendar.add(Calendar.DATE, -31);
            // retObj.setBeginDate(convertDateToString(calendar.getTime(),
            // "yyyyMMdd"));
            // retObj.setEndDate(convertDateToString(getDate(),
            // "yyyyMMdd"));

        } else if ("THREEMONTH".equals(queryTimeType)) {
            // 三个月内
            Calendar calendar = new GregorianCalendar();

            // 方式一，取从3个月前的1号到今天的日期
            // calendar.set(Calendar.DATE, 1);
            // calendar.add(Calendar.MONTH, -2);
            // retObj.setBeginDate(convertDateToString(calendar.getTime(),
            // "yyyyMMdd"));
            // retObj.setEndDate(convertDateToString(getDate(),
            // "yyyyMMdd"));

            // 方式二，取从93天前到今天的日期
            calendar.add(Calendar.MONTH, -3);
            retObj.setBeginDate(convertDateToString(calendar.getTime(),
                    "yyyyMMdd"));
            retObj.setEndDate(convertDateToString(getDate(), "yyyyMMdd"));
        } else {
            retObj = null;
        }
        return retObj;


    }

    public class TimeScope {

        // 开始时间
        private String beginDate;
        // 结束时间
        private String endDate;

        public String getBeginDate() {
            return beginDate;
        }

        public void setBeginDate(String beginDate) {
            this.beginDate = beginDate;
        }

        public String getEndDate() {
            return endDate;
        }

        public void setEndDate(String endDate) {
            this.endDate = endDate;
        }
    }
}
